package fu.ck;

import com.google.gson.Gson;
import fu.ck.Model.SettingModel;
import fu.ck.Model.TokenModel;
import fu.ck.ResultModel.ResultModel;
import fu.ck.Util.CalculationUtil;
import fu.ck.Util.GlobalUtil;
import fu.ck.Util.MysqlUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;

import java.util.HashMap;
import java.util.Random;

/**
 * Created by xuxingcan on 16-7-28.
 */
public class HttpPostServerInboundHandler extends ChannelInboundHandlerAdapter {
    private static final String FALSE = "false\n", TRUE = "true\n", PHONENUMBER = "phoneNumber", KEY = "key", USERNAME = "userName",
            AUTHTOKEN = "authToken", INDEX = "index", TIME = "time";
    private static final Gson gson = new Gson();
    private HttpPostRequestDecoder decoder;
    private HashMap<String, String> hashMap;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            HttpRequest request = (HttpRequest) msg;
            if (HttpMethod.POST == request.getMethod()) {
                decoder = new HttpPostRequestDecoder(request);
                hashMap = new HashMap<>();
            } else {
                decoder = null;
                String res = "please use post\n";
                FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
                        HttpResponseStatus.OK, Unpooled.wrappedBuffer(res.getBytes("UTF-8")));
                response.headers().set(io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE, "text/plain");
                response.headers().set(io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes());
                response.headers().set(io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
                ctx.write(response);
                ctx.flush();
            }
        } else if (msg instanceof HttpContent && decoder != null) {
            HttpContent content = (HttpContent) msg;
            decoder.offer(content);
            try {
                while (decoder.hasNext()) {
                    InterfaceHttpData data = decoder.next();
                    if (data != null) {
                        try {
                            if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
                                Attribute attribute = (Attribute) data;
                                hashMap.put(attribute.getName(), attribute.getValue());
                            }
                        } finally {
                            data.release();
                        }
                    }
                }
            } catch (Exception e) {
//                e.printStackTrace();
            }
//            for (HashMap.Entry<String, String> entry : hashMap.entrySet()) {
//                System.out.println(entry.getKey() + " = " + entry.getValue());
//            }
            if (content instanceof LastHttpContent) {
                ResultModel resultModel = new ResultModel();
                if (hashMap.containsKey(GlobalUtil.KEY_USER_ID)
                        && hashMap.containsKey(GlobalUtil.KEY_AUTH_CODE)) {
                    String user_id = hashMap.get(GlobalUtil.KEY_USER_ID);
                    String authCode = hashMap.get(GlobalUtil.KEY_AUTH_CODE);
                    if (hashMap.containsKey(GlobalUtil.KEY_BIND_USER_ID)) {
                        if (MysqlUtil.getInstance().bindUserId(authCode, user_id)) {
                            resultModel.errorMsg = "绑定成功";
                        } else {
                            resultModel.errorMsg = "绑定失败";
                        }
                    } else if (hashMap.containsKey(GlobalUtil.KEY_UNBIND_USER_ID)) {
                        if (MysqlUtil.getInstance().unBindUserId(authCode, user_id)) {
                            resultModel.errorMsg = "解绑成功";
                        } else {
                            resultModel.errorMsg = "解绑失败";
                        }
                    } else if (MysqlUtil.getInstance().isUserIdRight(authCode, user_id)) {
                        resultModel = getTokenOrCal(hashMap);
                    } else {
                        resultModel.errorMsg = "用户不存在或授权超时";
                    }
                } else {
                    resultModel.errorMsg = "非法请求";
                }
                String out = gson.toJson(resultModel);
                FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
                        HttpResponseStatus.OK, Unpooled.wrappedBuffer(out.getBytes("UTF-8")));
                response.headers().set(io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE, "text/plain");
                response.headers().set(io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes());
                response.headers().set(io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE);
                ctx.write(response);
                ctx.flush();
                ctx.close();
            }
        }
    }

    private ResultModel getTokenOrCal(HashMap<String, String> hashMap) {
        ResultModel resultModel = new ResultModel();
        String user_id = hashMap.get(GlobalUtil.KEY_USER_ID);
        if (hashMap.containsKey(GlobalUtil.KEY_GET_TOKEN)) {
            //getToken
            TokenModel tokenModel = new TokenModel();
            tokenModel.user_id = user_id;
            tokenModel.createTime = System.currentTimeMillis();
            tokenModel.token = getRandomString(10);
            resultModel.token = tokenModel.token;
            MysqlUtil.getInstance().updateTokenModel(tokenModel);
        } else if (hashMap.containsKey(GlobalUtil.KEY_TOKEN)) {
            //运算
            String token = hashMap.get(GlobalUtil.KEY_TOKEN);
            TokenModel tokenModel = MysqlUtil.getInstance().getTokenModel(user_id);
            if (tokenModel != null && token.equalsIgnoreCase(tokenModel.token)) {
                if (tokenModel.createTime < System.currentTimeMillis()
                        && tokenModel.createTime + 10 * 60 * 60 * 1000 > System.currentTimeMillis()) {
                    if (hashMap.containsKey(GlobalUtil.KEY_NATIVE_URL) && hashMap.containsKey(GlobalUtil.KEY_SEND_USER_ID)) {
                        resultModel = CalculationUtil.getNativeUrl(hashMap.get(GlobalUtil.KEY_SEND_USER_ID), hashMap.get(GlobalUtil.KEY_NATIVE_URL));
                    } else if (hashMap.containsKey(GlobalUtil.KEY_CALCULATE) && hashMap.containsKey(GlobalUtil.KEY_SETTING)) {
                        SettingModel settingModel = gson.fromJson(hashMap.get(GlobalUtil.KEY_SETTING), SettingModel.class);
                        resultModel = CalculationUtil.calculate(settingModel, hashMap.get(GlobalUtil.KEY_CALCULATE));
                    } else {
                        resultModel.errorMsg = "非法请求";
                    }
//                    tokenModel = new TokenModel();
//                    tokenModel.user_id = user_id;
//                    tokenModel.createTime = System.currentTimeMillis();
//                    tokenModel.token = getRandomString(10);
//                    resultModel.token = tokenModel.token;
//                    MysqlUtil.getInstance().updateTokenModel(tokenModel);
                } else {
                    resultModel.errorMsg = "token过时\n请重新开启机器人";
                }
            } else {
                resultModel.errorMsg = "token验证失败\n请重新开启机器人";
            }
        } else {
            resultModel.errorMsg = "请开启机器人";
        }
        return resultModel;
    }

    public static String getRandomString(int length) { //length表示生成字符串的长度
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        try {
            ResultModel resultModel = new ResultModel();
            resultModel.errorMsg = "服务器错误\n" + cause.getMessage();
            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK, Unpooled.wrappedBuffer(gson.toJson(resultModel).getBytes("UTF-8")));
            response.headers().set(io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE, "text/plain");
            response.headers().set(io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes());
            response.headers().set(io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE);
            ctx.writeAndFlush(response);
        } catch (Exception e) {
            e.printStackTrace();
        }
        ctx.close();
    }
}
